<template>
  <div class="kline-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>实时K线图</span>
        </div>
      </template>
      <div class="kline-controls">
        <el-select v-model="symbol" placeholder="请选择交易对" @change="fetchKlineData">
          <el-option label="BTCUSDT" value="BTCUSDT" />
          <el-option label="ETHUSDT" value="ETHUSDT" />
          <el-option label="BNBUSDT" value="BNBUSDT" />
          <el-option label="XRPUSDT" value="XRPUSDT" />
          <el-option label="SOLUSDT" value="SOLUSDT" />
        </el-select>
        <el-select v-model="interval" placeholder="请选择周期" @change="fetchKlineData">
          <el-option label="1分钟" value="1m" />
          <el-option label="5分钟" value="5m" />
          <el-option label="15分钟" value="15m" />
          <el-option label="1小时" value="1h" />
          <el-option label="4小时" value="4h" />
          <el-option label="1天" value="1d" />
        </el-select>
      </div>
      <div ref="klineChart" class="chart-container"></div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import * as echarts from 'echarts';
import { ElMessage } from 'element-plus';

const symbol = ref('BTCUSDT');
const interval = ref('1h');
const klineChart = ref(null);
let chartInstance = null;
let socket = null;
let timer = null;

onMounted(() => {
  initChart();
  fetchKlineData();
  connectWebSocket();
});

onUnmounted(() => {
  // 清理资源
  if (socket) {
    socket.close();
    socket = null;
  }
  if (timer) {
    clearInterval(timer);
    timer = null;
  }
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
});

function initChart() {
  chartInstance = echarts.init(klineChart.value);
  const option = {
    title: {
      text: `${symbol.value} ${interval.value} K线图`,
      left: 'center'
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross'
      }
    },
    legend: {
      data: ['K线', '成交量'],
      bottom: 0
    },
    grid: [
      {
        left: '3%',
        right: '3%',
        top: '15%',
        bottom: '15%'
      },
      {
        left: '3%',
        right: '3%',
        top: '80%',
        bottom: '3%',
        height: '15%'
      }
    ],
    xAxis: [
      {
        type: 'category',
        data: [],
        axisLine: { onZero: false },
        axisTick: { show: false },
        axisLabel: {
          interval: 5 // 只显示部分标签，避免拥挤
        },
        splitLine: { show: false }
      },
      {
        type: 'category',
        data: [],
        gridIndex: 1,
        axisLabel: { show: false },
        axisTick: { show: false },
        axisLine: { show: false },
        splitLine: { show: false }
      }
    ],
    yAxis: [
      {
        type: 'value',
        scale: true,
        position: 'right',
        axisLine: { show: false },
        axisTick: { show: false }
      },
      {
        type: 'value',
        scale: true,
        position: 'left',
        axisLine: { show: false },
        axisTick: { show: false },
        splitLine: { show: false }
      },
      {
        type: 'value',
        scale: true,
        gridIndex: 1,
        axisLabel: { show: false },
        axisLine: { show: false },
        axisTick: { show: false },
        splitLine: { show: false }
      }
    ],
    series: [
      {
        name: 'K线',
        type: 'candlestick',
        data: [],
        itemStyle: {
          color: '#27AE60',
          color0: '#E74C3C',
          borderColor: '#27AE60',
          borderColor0: '#E74C3C'
        },
        markPoint: {
          data: [
            { type: 'max', name: '最大值' },
            { type: 'min', name: '最小值' }
          ]
        },
        markLine: {
          data: [
            { type: 'average', name: '平均值' }
          ]
        }
      },
      {
        name: '成交量',
        type: 'bar',
        xAxisIndex: 1,
        yAxisIndex: 2,
        data: [],
        itemStyle: {
          color: function(params) {
            // 根据K线涨跌设置成交量颜色
            const candleData = chartInstance.getOption().series[0].data[params.dataIndex];
            if (candleData) {
              return candleData[1] > candleData[0] ? '#27AE60' : '#E74C3C';
            }
            return '#999';
          }
        }
      }
    ]
  };
  chartInstance.setOption(option);
  window.addEventListener('resize', () => chartInstance.resize());
}

function fetchKlineData() {
  // 调用API获取K线数据
  ElMessage({
    type: 'info',
    message: `正在获取${symbol.value} ${interval.value} K线数据...`
  });

  fetch(`/api/kline?symbol=${symbol.value}&interval=${interval.value}`)
    .then(response => response.json())
    .then(data => {
      if (data.error) {
        ElMessage({
          type: 'error',
          message: `获取K线数据失败: ${data.error}`
        });
        return;
      }

      const dateData = data.map(item => new Date(item.timestamp).toISOString().replace('Z', '').replace('T', ' ').split('.')[0]);
      const candleData = data.map(item => [parseFloat(item.open), parseFloat(item.high), parseFloat(item.low), parseFloat(item.close)]);
      const volumeData = data.map(item => parseFloat(item.volume));

      // 更新图表
      chartInstance.setOption({
        title: {
          text: `${symbol.value} ${interval.value} K线图`
        },
        xAxis: [
          {
            data: dateData
          },
          {
            data: dateData
          }
        ],
        series: [
          {
            data: candleData
          },
          {
            data: volumeData
          }
        ]
      });

      ElMessage({
        type: 'success',
        message: `K线数据获取成功`
      });
    })
    .catch(error => {
      ElMessage({
        type: 'error',
        message: `获取K线数据失败: ${error.message}`
      });
      console.error('获取K线数据失败:', error);
    });
}

function generateMockKlineData() {
  const data = [];
  const now = Date.now();
  let basePrice = 40000;
  let baseVolume = 100;
  const intervalMs = getIntervalMs(interval.value);

  for (let i = 30; i >= 0; i--) {
    const time = new Date(now - i * intervalMs).toISOString().replace('Z', '').replace('T', ' ').split('.')[0];
    const open = parseFloat((basePrice + (Math.random() - 0.5) * 1000).toFixed(2));
    const high = parseFloat((open + Math.random() * 500).toFixed(2));
    const low = parseFloat((open - Math.random() * 500).toFixed(2));
    const close = parseFloat((low + Math.random() * (high - low)).toFixed(2));
    const volume = parseFloat((baseVolume + (Math.random() - 0.5) * 50).toFixed(2));

    data.push([time, open, high, low, close, volume]);

    // 更新下一根K线的基础价格
    basePrice = close;
    baseVolume = volume;
  }

  return data;
}

function getIntervalMs(interval) {
  switch (interval) {
    case '1m': return 60 * 1000;
    case '5m': return 5 * 60 * 1000;
    case '15m': return 15 * 60 * 1000;
    case '1h': return 60 * 60 * 1000;
    case '4h': return 4 * 60 * 60 * 1000;
    case '1d': return 24 * 60 * 60 * 1000;
    default: return 60 * 60 * 1000;
  }
}

function connectWebSocket() {
  // 关闭之前的定时器
  if (timer) {
    clearInterval(timer);
    timer = null;
  }

  // 每隔5秒获取一次最新K线数据
  timer = setInterval(() => {
    fetch(`/api/kline/realtime?symbol=${symbol.value}&interval=${interval.value}`)
      .then(response => response.json())
      .then(data => {
        if (data.error) {
          console.error('获取实时K线数据失败:', data.error);
          return;
        }

        const option = chartInstance.getOption();
        const series = option.series[0];
        if (series && series.data && series.data.length > 0) {
          // 获取当前最后一根K线
          const lastCandle = series.data[series.data.length - 1];
          const lastVolume = option.series[1].data[option.series[1].data.length - 1];
          const lastDate = option.xAxis[0].data[option.xAxis[0].data.length - 1];

          // 使用真实数据更新最后一根K线
          const newOpen = parseFloat(data.open);
          const newHigh = parseFloat(data.high);
          const newLow = parseFloat(data.low);
          const newClose = parseFloat(data.close);
          const newVolume = parseFloat(data.volume);

          // 如果是新的K线周期，则添加新K线
          const currentTime = new Date(data.timestamp);
          const lastTime = new Date(lastDate.replace(' ', 'T') + 'Z');
          const intervalMs = getIntervalMs(interval.value);

          if (currentTime - lastTime >= intervalMs) {
            // 添加新K线
            chartInstance.setOption({
              xAxis: [
                {
                  data: [...option.xAxis[0].data, currentTime.toISOString().replace('Z', '').replace('T', ' ').split('.')[0]]
                },
                {
                  data: [...option.xAxis[1].data, currentTime.toISOString().replace('Z', '').replace('T', ' ').split('.')[0]]
                }
              ],
              series: [
                {
                  data: [...series.data, [newOpen, newHigh, newLow, newClose]]
                },
                {
                  data: [...option.series[1].data, newVolume]
                }
              ]
            });
          } else {
            // 更新当前K线
            chartInstance.setOption({
              series: [
                {
                  data: [
                    ...series.data.slice(0, series.data.length - 1),
                    [lastCandle[0], newOpen, newHigh, newLow, newClose]
                  ]
                },
                {
                  data: [
                    ...option.series[1].data.slice(0, option.series[1].data.length - 1),
                    newVolume
                  ]
                }
              ]
            });
          }
        }
      })
      .catch(error => {
        console.error('获取实时K线数据失败:', error);
      });
  }, 5000); // 每5秒更新一次
}
</script>

<style scoped>
.kline-container {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.kline-controls {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
}

.chart-container {
  width: 100%;
  height: 600px;
}
</style>